package com.zzw.redislimter;

import lombok.Getter;
import lombok.Setter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.support.HasRouteId;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.http.HttpStatus;

/**
 * @author Administrator
 */
public class RLimterGatewayFilterFactory extends AbstractGatewayFilterFactory<RLimterGatewayFilterFactory.Config2> {

    private final RRedisRateLimiter redisRateLimiter;

    public RLimterGatewayFilterFactory(RRedisRateLimiter redisRateLimiter) {
        super(Config2.class);
        this.redisRateLimiter = redisRateLimiter;
    }

    @Override
    public GatewayFilter apply(Config2 config) {
        return (exchange, chain) -> redisRateLimiter.isAllowed(config.limterKey, config.rate, config.crust).flatMap(response -> {
            if (response.isAllowed()) {
                return chain.filter(exchange);
            } else {
                ServerWebExchangeUtils.setResponseStatus(exchange, config.getStatusCode());
                return exchange.getResponse().setComplete();
            }
        });
    }

    @Setter
    @Getter
    public static class Config2 implements HasRouteId {
        private String routeId;
        private String limterKey = "default";
        private String rate = "1";
        private String crust = "1";
        private HttpStatus statusCode = HttpStatus.TOO_MANY_REQUESTS;

        @Override
        public String getRouteId() {
            return routeId;
        }

        @Override
        public void setRouteId(String routeId) {
            this.routeId = routeId;
        }
    }
}
